package hugeBlock

import (
	"learn-opengl/camera"
	"learn-opengl/object/block"
	"learn-opengl/object/tree"
	"learn-opengl/opengl/shader"
	. "learn-opengl/util"
	"math"
	"math/rand"
	"time"

	"github.com/go-gl/mathgl/mgl32"
)

type Plant struct {
	pos mgl32.Vec3
	kind int
}

func NewPlant(pos mgl32.Vec3,kind int) *Plant {
	return &Plant{
		pos: pos,
		kind: kind,
	}
}


type HugeBlock struct {
	pos IV3
	// 指明chunk块的类型
	kind int
	// 保存可以被看到的立方体
	Show []mgl32.Vec3
	// 是否存在---方便打碎以及碰撞检测
	Blocks map[IV3]int
	Tree []*tree.Tree
	hei [][]int
}

func NewHugeBlock(pos IV3,kind int) *HugeBlock {
	h := &HugeBlock{
		pos: pos,
		kind: kind,
		Blocks: make(map[IV3]int),
	}
	h.hugeBlockInit()
	return h
}

// 是否存在某个block
func (h *HugeBlock) HasBlock(pos IV3) int {
	return h.Blocks[pos]
}

// 初始化生成block--可以加入噪声
func (h *HugeBlock) hugeBlockInit() {
	rand.Seed(time.Now().Unix())
	// 初始化周围
	hei := make([][]int,0,16)
	for i:=0;i<15;i++ {
		hei = append(hei, make([]int, 15))
	}
	PerlinNoise(hei)
	h.hei = hei

	for i:=0;i<15;i++ {
		for j:=0;j<15;j++ {
			for k:=0;k<=hei[i][j];k++ {
				h.Blocks[IV3{h.pos[0]+i,h.pos[1]+k,h.pos[2]+j}] = h.kind
			}
			// if 
			d := rand.Int() %200
			if d>=17 && d<=23  {
				h.Blocks[IV3{h.pos[0]+i,h.pos[1]+1+hei[i][j],h.pos[2]+j}] = d
			}
			if d==15 {
				tt := rand.Int31()
				if tt%2==0 {
					continue
				}
				t := tree.NewTree(IV3{h.pos[0]+i,h.pos[1]+1+hei[i][j],h.pos[2]+j})
				for key,val := range t.Data {
					h.Blocks[key] = val
				}
			}
		}

	}
}


func (h *HugeBlock) Draw(camera *camera.Camera,shader *shader.Shader) {

	// for i:=0;i<15;i++ {
	// 	for j:=0;j<15;j++ {
	// 		for k:=0;k<=h.hei[i][j]+1;k++ {
	// 			if(i!=0 && i!=14 && j!=0 && j!=14 && k!= h.hei[i][j]) {
	// 				if(k <= h.hei[i+1][j] && k<= h.hei[i][j+1] && k<=h.hei[i-1][j] && k<=h.hei[i][j-1]) {
	// 					continue
	// 				}
	// 			}
	// 			item := IV3{h.pos[0]+i,h.pos[1]+k,h.pos[2]+j}
	// 			tem := mgl32.Vec3{float32(h.pos[0]+i),float32(h.pos[1]+k),float32(h.pos[2]+j)}
	// 			cPos := camera.GetPos()
	// 			front := camera.GetFront()
	// 			p := tem.Sub(cPos)
	// 			angle := math.Acos(float64(front.Normalize().Dot(p.Normalize())))
	// 			if p.Len()>50 && tem[1] < 10 {
	// 				continue
	// 			}
	// 			if angle < math.Pi/2 && h.Blocks[item] != 0 {
	// 				block.Blocks[h.Blocks[item]].Draw(shader,tem)
	// 			}
	// 		}
	// 	}
	// }

	for item,val := range h.Blocks {
		i,j,k := item[0]-h.pos[0],item[2]-h.pos[2],item[1]-h.pos[1]
		if(val!=15 && i!=0 && i!=14 && j!=0 && j!=14 && k!= h.hei[i][j]) {
			if(k <= h.hei[i+1][j] && k<= h.hei[i][j+1] && k<=h.hei[i-1][j] && k<=h.hei[i][j-1]) {
				continue
			}
		}
		tem := mgl32.Vec3{float32(h.pos[0]+i),float32(h.pos[1]+k),float32(h.pos[2]+j)}
		cPos := camera.GetPos()
		front := camera.GetFront()
		p := tem.Sub(cPos)
		angle := math.Acos(float64(front.Normalize().Dot(p.Normalize())))
		if p.Len()>50 && tem[1] < 10 {
			continue
		}
		if angle < math.Pi/2 {
			block.Blocks[val].Draw(shader,tem)
		}
	}

	// for i:=0;i<len(h.Show);i++ {
	// 	// 圆锥体优化
	// 	cPos := camera.GetPos()
	// 	front := camera.GetFront()
	// 	p := h.Show[i].Sub(cPos)
	// 	angle := math.Acos(float64(front.Normalize().Dot(p.Normalize())))
	// 	if p.Len()>40 && h.Show[i][1] < 10 {
	// 		continue
	// 	}
	// 	if angle < math.Pi/4 {
	// 		block.Blocks[h.kind].Draw(shader,h.Show[i])
	// 	}
	// }
	// for i:=0;i<len(h.Plants);i++ {
	// 	// 圆锥体优化
	// 	cPos := camera.GetPos()
	// 	front := camera.GetFront()
	// 	p := h.Plants[i].pos.Sub(cPos)
	// 	angle := math.Acos(float64(front.Normalize().Dot(p.Normalize())))
	// 	if p.Len()>40 && h.Plants[i].pos[1] < 10 {
	// 		continue
	// 	}
	// 	if angle < math.Pi/4 {
	// 		block.Blocks[h.Plants[i].kind].Draw(shader,h.Plants[i].pos)
	// 	}
	// }
}


